import type { IDraggable, IMatrix } from "../core/types";

type RotateCursor = {
  src: string;
  x: number;
  y: number;
};
export class DomUtils {
  static getDomBoundary(el: HTMLElement | null, zoom: number) {
    if (el) {
      const domRect = el.getBoundingClientRect();
      return {
        width: domRect.width / zoom,
        height: domRect.height / zoom,
        left: domRect.left / zoom,
        top: domRect.top / zoom,
        right: domRect.right / zoom,
        bottom: domRect.bottom / zoom
      };
    }
  }

  static getDomCenterPosition = (element: HTMLElement | null, rect: IDraggable) => {
    const { x, y, w, h } = rect;
    if (element) {
      const rectInfo = element.getBoundingClientRect();
      return {
        centerX: rectInfo.left + rectInfo.width / 2,
        centerY: rectInfo.top + rectInfo.height / 2
      };
    }
    return {
      centerX: x + w / 2,
      centerY: y + h / 2
    };
  };

  static getDomMatrix(element: HTMLElement): IMatrix {
    const matrix = window.getComputedStyle(element).transform;
    const matrixValues = matrix.match(/-?[\d\.]+/g);
    if (matrixValues) {
      return {
        a: parseFloat(matrixValues[0]!),
        b: parseFloat(matrixValues[1]!),
        c: parseFloat(matrixValues[2]!),
        d: parseFloat(matrixValues[3]!),
        x: parseFloat(matrixValues[4]!),
        y: parseFloat(matrixValues[5]!)
      };
    }
    return {
      a: 1,
      b: 0,
      c: 0,
      d: 1,
      x: 0,
      y: 0
    };
  }
  /* 获取旋转的鼠标方向 */
  static setRotatedCursor(imagePath: string, rotation: number = 0): Promise<RotateCursor> {
    return new Promise((resolve, reject) => {
      const img = new Image();

      img.onload = () => {
        const canvas = document.createElement("canvas");
        const ctx = canvas.getContext("2d");
        // 计算对角线长度以容纳旋转后的图片
        const diagonal = Math.sqrt(img.width * img.width + img.height * img.height);
        canvas.width = diagonal;
        canvas.height = diagonal;
        if (ctx) {
          // 清除画布并旋转绘图上下文
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          ctx.translate(canvas.width / 2, canvas.height / 2);
          ctx.rotate((rotation * Math.PI) / 180);
          // 居中绘制图片
          ctx.drawImage(img, -img.width / 2, -img.height / 2, img.width, img.height);
          ctx.rotate((-rotation * Math.PI) / 180);
          ctx.translate(-canvas.width / 2, -canvas.height / 2);

          const x = Math.floor(img.width / 2);
          const y = Math.floor(img.height / 2);

          resolve({
            src: canvas.toDataURL("image/png", 1.0),
            x,
            y
          });
        } else {
          reject(new Error("无法获取Canvas上下文"));
        }
      };

      img.onerror = () => {
        reject(new Error(`无法加载图片: ${imagePath}`));
      };

      img.src = imagePath;
    });
  }
  static onClickOutside(
    targetElement: HTMLElement | null,
    callback: (event: MouseEvent | TouchEvent) => void
  ) {
    // 事件处理核心逻辑
    const handleEvent = (event: Event) => {
      // 1. 目标元素不存在时直接返回
      if (!targetElement) return;

      // 2. 转换事件类型并处理右键点击（默认只处理左键）
      const isMouseEvent = event instanceof MouseEvent;
      if (isMouseEvent && event.button !== 0) return; // 过滤非左键点击

      // 3. 检查点击是否在目标元素内部
      const isClickInside = targetElement.contains(event.target as Node);
      if (isClickInside) return;

      // 4. 执行回调（使用类型断言确保事件类型正确）
      callback(event as MouseEvent | TouchEvent);
    };

    // 5. 绑定事件（同时支持鼠标和触摸事件）
    document.addEventListener("mousedown", handleEvent);
    document.addEventListener("touchstart", handleEvent);

    // 6. 返回清理函数（支持多次调用时的幂等性）
    let isRemoved = false;
    return () => {
      if (isRemoved) return;
      document.removeEventListener("mousedown", handleEvent);
      document.removeEventListener("touchstart", handleEvent);
      isRemoved = true;
    };
  }
  static getCenter = (element: HTMLElement) => {
    if (element) {
      const rectInfo = element.getBoundingClientRect();
      return {
        centerX: rectInfo.left + rectInfo.width / 2,
        centerY: rectInfo.top + rectInfo.height / 2
      };
    }
  };
}
